package com.miracle.system.service.impl;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

import com.miracle.common.utils.StringUtils;
import com.miracle.system.domain.SysResource;
import com.miracle.system.domain.TreeEntity;
import com.miracle.system.domain.vo.ResourceMetaVo;
import com.miracle.system.domain.vo.ResourceVo;
import com.miracle.system.mapper.SysRoleResourceMapper;
import org.springframework.stereotype.Service;
import com.miracle.system.domain.SysUser;
import com.miracle.system.mapper.SysResourceMapper;
import com.miracle.system.service.SysResourceService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 菜单 业务层处理
 *
 * @author miracle
 */
@Service
public class SysResourceServiceImpl implements SysResourceService
{
    @Resource
    private SysResourceMapper resourceMapper;
    @Resource
    private SysRoleResourceMapper roleResourceMapper;

    /**
     * 根据用户ID查询权限
     *
     * @param userId 用户ID
     * @return 权限列表
     */
    @Override
    public List<String> selectPermissionListByUserId(Integer userId)
    {
        List<String> perms = resourceMapper.selectPermissionListByUserId(userId);
        return perms;
    }

    @Override
    public List<String> selectPermissionListByUser(SysUser user) {

        return resourceMapper.selectPermissionListByUserId(user.getUserId());
    }

    /**
     * 根据用户ID查询菜单列表(登陆后获取菜单)
     *
     * @param userId 用户ID
     * @return 菜单列表
     */
    @Override
    public List<SysResource> selectResourceByUserId(Integer userId) {
        List<SysResource>  resourceList = resourceMapper.selectResourceByUserId(userId);
        return getChildrenByParentId(resourceList, 0);
    }

    @Override
    public List<SysResource> selectResourceByRoleId(Integer roleId) {
        return resourceMapper.selectResourceByRoleId(roleId);
    }

    /**
     * 传给前台可识别的数据形式
     *
     * @param resources
     * @return 菜单树列表
     */
    @Override
    public List<ResourceVo> buildResources(List<SysResource> resources) {
        List<ResourceVo> resourceTree = new LinkedList<ResourceVo>();

        for (SysResource resource: resources) {
            ResourceVo  resourceVo = new ResourceVo();
            resourceVo.setName(resource.getResourceName());
            resourceVo.setPath(resource.getParentResourceId()==0?"/"+resource.getPath():resource.getPath());
            if (resource.getParentResourceId() == 0){
                resourceVo.setComponent(StringUtils.isEmpty(resource.getUrl())?"Layout":resource.getUrl());
            } else {
                resourceVo.setComponent(resource.getUrl());
            }
            resourceVo.setHidden("disabled".equals(resource.getStatus()));
            resourceVo.setMeta(new ResourceMetaVo(resource.getResourceName(), resource.getImagePath(), true));
            List<SysResource> childResource = resource.getChildren();
            if (!childResource.isEmpty() && childResource.size() > 0){
                resourceVo.setAlwaysShow(true);
                resourceVo.setRedirect("noredirect");
                resourceVo.setChildren(buildResources(childResource));
            }
            resourceTree.add(resourceVo);
        }
        return resourceTree;
    }

    @Override
    public List<TreeEntity> buildResourceTree(List<SysResource> resources) {

        List<SysResource> resourceList = getChildrenByParentId(resources, 0);
        return resourceList.stream().map(TreeEntity::new).collect(Collectors.toList());
    }

    @Override
    public List<SysResource> selectResourceList(SysResource resource) {
        return resourceMapper.selectResourceList(resource);
    }

    @Override
    public Integer insertResource(SysResource resource) {
        resource = setParentIsBranch(resource); //设置父节点为分支节点
        return resourceMapper.insertResource(resource);
    }

    @Override
    public Integer updateResource(SysResource resource) {
        resource = setParentIsBranch(resource);
        return resourceMapper.updateResource(resource);
    }

    @Override
    public List<SysResource> selectResourceByParentResourceId(Integer parentResourceId) {

        return resourceMapper.selectResourceByParentResourceId(parentResourceId);
    }

    @Override
    public SysResource selectResourceByResourceId(Integer resourceId) {
        return resourceMapper.selectResourceByResourceId(resourceId);
    }

    @Override
    @Transactional
    public Integer deleteResourceByResourceIds(Integer[] resourceIds) {
        //暂时未考虑其父节点是否为分支节点的设置
        roleResourceMapper.deleteRoleResourceByResourceIds(resourceIds);
        return resourceMapper.deleteResourceByResourceIds(resourceIds);
    }

    @Override
    public SysResource remoteCheckResource(SysResource resource) {
        return resourceMapper.remoteCheckResource(resource);
    }

    public List<SysResource> getChildrenByParentId(List<SysResource> resources, Integer parentResourceId){
        List<SysResource> resourceList = new ArrayList<SysResource>();
        for (SysResource resource: resources) {
            resource.setParentResourceId(resource.getParentResourceId());

            if (resource.getParentResourceId().intValue() == parentResourceId){
                getChildrenListByConvert(resources, resource);
                resourceList.add(resource);
            }
        }
        return resourceList;
    }

    public void getChildrenListByConvert(List<SysResource> resources, SysResource resource){

        List<SysResource> childrenList = getChildrenByParentId(resources, resource.getResourceId());
        resource.setChildren(childrenList);
        if (!childrenList.isEmpty() && childrenList.size() > 0){
            for (SysResource children: childrenList) {
                getChildrenListByConvert(resources, children);
            }
        }
    }

    private SysResource setParentIsBranch(SysResource resource) {
        Integer parentResourceId = resource.getParentResourceId();
        SysResource parentResource = resourceMapper.selectResourceByResourceId(parentResourceId);
        if ("N".equals(parentResource.getIsBranch())){
            resource.setIsBranch("Y");
        }
        return resource;
    }
}
